﻿using System;
using System.Threading.Tasks;
using DNT.RavenQA.Core.Extensions;
using DNT.RavenQA.Core.Models;
using DNT.RavenQA.Web.Infrastructure.Indexing;
using Raven.Client;

namespace DNT.RavenQA.Web.Infrastructure.Commands
{
    public class UpdateUserNameCommand : RavenCommand<UpdateUserNameCommand.Input, VoidResult>
    {
        public struct Input
        {
            public String UserId;
            public String UserName;
        }

        public UpdateUserNameCommand(Input parameter)
            : base(parameter) { }

        public override VoidResult Execute(IDocumentSession session)
        {
            session.EnsureIsNotNull("session");

            var user = session.Load<User>(Parameter.UserId);

            if (user.IsNull())
                throw new NonExistingUserException(String.Format("Cannot find a used with id '{0}'.", user.Id));

            user.ChangeName(Parameter.UserName);
            UpdateDenormalizedReference(session);
            return VoidResult.Instance;
        }

        private void UpdateDenormalizedReference(IDocumentSession session)
        {
            Task.Factory.StartNew(() => session.Advanced
                                            .DocumentStore
                                            .DatabaseCommands
                                            .UpdateByIndex(ContributesByAuthorIdIndex.INDEX_NAME,
                                                           ContributesByAuthorIdIndex.BuildQueryContributesByUserId(Parameter.UserId),
                                                           new[] { ContributesByAuthorIdIndex.BuildContributesPatchRequest(Parameter.UserName) },
                                                           allowStale: false),
                                  TaskCreationOptions.LongRunning);
        }
    }
}